'use strict';

const { Service } = require('egg');

class OutgoingInvoiceService extends Service {
  /**
   * 获取销项发票列表
   * @param {Object} query - 查询参数
   * @param {Number} organizationId - 组织ID
   */
  async getOutgoingInvoices(query, organizationId) {
    const { ctx } = this;
    const { page = 1, pageSize = 20, invoiceNumber, sellerName, buyerName, startDate, endDate } = query;
    
    try {
      const where = { organizationId };
      
      // 添加查询条件
      if (invoiceNumber) {
        where.invoiceNumber = { [ctx.app.Sequelize.Op.like]: `%${invoiceNumber}%` };
      }
      
      if (sellerName) {
        where.sellerName = { [ctx.app.Sequelize.Op.like]: `%${sellerName}%` };
      }
      
      if (buyerName) {
        where.buyerName = { [ctx.app.Sequelize.Op.like]: `%${buyerName}%` };
      }
      
      if (startDate && endDate) {
        where.invoiceDate = {
          [ctx.app.Sequelize.Op.between]: [new Date(startDate), new Date(endDate)]
        };
      }
      
      const result = await ctx.model.OutgoingInvoiceModel.findAndCountAll({
        where,
        limit: parseInt(pageSize),
        offset: (parseInt(page) - 1) * parseInt(pageSize),
        order: [['createdAt', 'DESC']]
      });
      
      return {
        items: result.rows,
        total: result.count,
        page: parseInt(page),
        pageSize: parseInt(pageSize)
      };
    } catch (error) {
      ctx.logger.error('[OutgoingInvoice] 获取发票列表失败:', error);
      throw error;
    }
  }
  
  /**
   * 根据ID获取销项发票详情
   * @param {Number} id - 发票ID
   * @param {Number} organizationId - 组织ID
   */
  async getOutgoingInvoiceById(id, organizationId) {
    const { ctx } = this;
    
    try {
      const invoice = await ctx.model.OutgoingInvoiceModel.findOne({
        where: {
          id,
          organizationId
        }
      });
      
      if (!invoice) {
        ctx.throw(404, '发票不存在');
      }
      
      return invoice;
    } catch (error) {
      ctx.logger.error('[OutgoingInvoice] 获取发票详情失败:', error);
      throw error;
    }
  }
  
  /**
   * 创建销项发票
   * @param {Object} invoiceData - 发票数据
   * @param {Number} organizationId - 组织ID
   */
  async createOutgoingInvoice(invoiceData, organizationId) {
    const { ctx } = this;
    
    try {
      // 检查发票号码是否已存在
      const existingInvoice = await ctx.model.OutgoingInvoiceModel.findOne({
        where: {
          invoiceNumber: invoiceData.invoiceNumber,
          organizationId
        }
      });
      
      if (existingInvoice) {
        ctx.throw(400, '发票号码已存在');
      }
      
      const invoice = await ctx.model.OutgoingInvoiceModel.create({
        ...invoiceData,
        organizationId
      });
      
      ctx.logger.info(`[OutgoingInvoice] 创建发票: ${invoice.invoiceNumber}`);
      return invoice;
    } catch (error) {
      ctx.logger.error('[OutgoingInvoice] 创建发票失败:', error);
      throw error;
    }
  }
  
  /**
   * 更新销项发票
   * @param {Number} id - 发票ID
   * @param {Object} invoiceData - 发票数据
   * @param {Number} organizationId - 组织ID
   */
  async updateOutgoingInvoice(id, invoiceData, organizationId) {
    const { ctx } = this;
    
    try {
      const invoice = await ctx.model.OutgoingInvoiceModel.findOne({
        where: {
          id,
          organizationId
        }
      });
      
      if (!invoice) {
        ctx.throw(404, '发票不存在');
      }
      
      // 检查发票号码是否被其他发票使用
      if (invoiceData.invoiceNumber && invoiceData.invoiceNumber !== invoice.invoiceNumber) {
        const existingInvoice = await ctx.model.OutgoingInvoiceModel.findOne({
          where: {
            invoiceNumber: invoiceData.invoiceNumber,
            organizationId,
            id: { [ctx.app.Sequelize.Op.ne]: id }
          }
        });
        
        if (existingInvoice) {
          ctx.throw(400, '发票号码已存在');
        }
      }
      
      await invoice.update(invoiceData);
      ctx.logger.info(`[OutgoingInvoice] 更新发票: ${invoice.invoiceNumber}`);
      return invoice;
    } catch (error) {
      ctx.logger.error('[OutgoingInvoice] 更新发票失败:', error);
      throw error;
    }
  }
  
  /**
   * 删除销项发票
   * @param {Number} id - 发票ID
   * @param {Number} organizationId - 组织ID
   */
  async deleteOutgoingInvoice(id, organizationId) {
    const { ctx } = this;
    
    try {
      const invoice = await ctx.model.OutgoingInvoiceModel.findOne({
        where: {
          id,
          organizationId
        }
      });
      
      if (!invoice) {
        ctx.throw(404, '发票不存在');
      }
      
      await invoice.destroy();
      ctx.logger.info(`[OutgoingInvoice] 删除发票: ${invoice.invoiceNumber}`);
    } catch (error) {
      ctx.logger.error('[OutgoingInvoice] 删除发票失败:', error);
      throw error;
    }
  }
  
  /**
   * 创建或更新销项发票
   * @param {Object} invoiceData - 发票数据
   * @param {Number} organizationId - 组织ID
   */
  async createOrUpdateInvoice(invoiceData, organizationId) {
    const { ctx } = this;
    
    try {
      // 检查发票是否已存在
      const existingInvoice = await ctx.model.OutgoingInvoiceModel.findOne({
        where: {
          invoiceNumber: invoiceData.invoiceNumber,
          organizationId: organizationId
        }
      });
      
      const invoicePayload = {
        invoiceNumber: invoiceData.invoiceNumber,
        invoiceCode: invoiceData.invoiceCode,
        invoiceTypeCode: invoiceData.invoiceTypeCode,
        invoiceKindCode: invoiceData.invoiceKindCode,
        invoiceStatusCode: invoiceData.invoiceStatusCode,
        isRedInvoice: invoiceData.isRedInvoice,
        sellerTaxNumber: invoiceData.sellerTaxNumber,
        sellerName: invoiceData.sellerName,
        buyerTaxNumber: invoiceData.buyerTaxNumber,
        buyerName: invoiceData.buyerName,
        invoiceDate: invoiceData.invoiceDate,
        totalAmount: invoiceData.totalAmount,
        taxAmount: invoiceData.taxAmount,
        totalTaxAmount: invoiceData.totalTaxAmount,
        invoiceSource: invoiceData.invoiceSource,
        issuer: invoiceData.issuer,
        taxBureauCode: invoiceData.taxBureauCode,
        taxBureauName: invoiceData.taxBureauName,
        organizationId: organizationId
      };
      
      if (existingInvoice) {
        // 更新现有发票
        await existingInvoice.update(invoicePayload);
        ctx.logger.info(`[Invoice] 更新发票: ${invoiceData.invoiceNumber}`);
        return existingInvoice;
      } else {
        // 创建新发票
        const newInvoice = await ctx.model.OutgoingInvoiceModel.create(invoicePayload);
        ctx.logger.info(`[Invoice] 创建发票: ${invoiceData.invoiceNumber}`);
        return newInvoice;
      }
    } catch (error) {
      ctx.logger.error('[Invoice] 处理发票数据失败:', error);
      throw error;
    }
  }
  
  /**
   * 批量处理发票数据
   * @param {Array} invoiceList - 发票列表
   * @param {Number} organizationId - 组织ID
   */
  async batchProcessInvoices(invoiceList, organizationId) {
    const { ctx } = this;
    
    try {
      const results = {
        created: 0,
        updated: 0,
        failed: 0
      };
      
      for (const invoiceData of invoiceList) {
        try {
          const result = await this.createOrUpdateInvoice(invoiceData, organizationId);
          if (result.isNewRecord) {
            results.created++;
          } else {
            results.updated++;
          }
        } catch (error) {
          results.failed++;
          ctx.logger.error(`[Invoice] 处理发票失败: ${invoiceData.invoiceNumber}`, error);
        }
      }
      
      ctx.logger.info(`[Invoice] 批量处理完成 - 创建: ${results.created}, 更新: ${results.updated}, 失败: ${results.failed}`);
      return results;
    } catch (error) {
      ctx.logger.error('[Invoice] 批量处理发票失败:', error);
      throw error;
    }
  }
  
  /**
   * 从插件数据中提取发票信息
   * @param {Object} pluginData - 插件数据
   */
  async extractInvoiceFromPluginData(pluginData) {
    const { ctx } = this;
    
    try {
      // 检查是否为发票数据
      if (!this.isInvoiceData(pluginData)) {
        ctx.logger.info('[Invoice] 非发票数据，跳过处理');
        return null;
      }
      
      // 提取发票列表
      const invoiceList = this.parseInvoiceList(pluginData);
      if (!invoiceList || invoiceList.length === 0) {
        ctx.logger.warn('[Invoice] 未找到发票数据');
        return null;
      }
      
      // 获取组织ID（这里简化处理，实际应该从上下文获取）
      const organizationId = 1; // 默认组织ID，实际应从用户上下文获取
      
      // 批量处理发票
      const results = await this.batchProcessInvoices(invoiceList, organizationId);
      
      return {
        success: true,
        data: results,
        invoiceCount: invoiceList.length
      };
    } catch (error) {
      ctx.logger.error('[Invoice] 从插件数据提取发票信息失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }
  
  /**
   * 从插件数据中提取进项发票信息
   * @param {Object} pluginData - 插件数据
   */
  async extractIncomingInvoiceFromPluginData(pluginData) {
    const { ctx } = this;
    
    try {
      // 检查是否为发票数据
      if (!this.isInvoiceData(pluginData)) {
        ctx.logger.info('[IncomingInvoice] 非发票数据，跳过处理');
        return null;
      }
      
      // 提取发票列表
      const invoiceList = this.parseIncomingInvoiceList(pluginData);
      if (!invoiceList || invoiceList.length === 0) {
        ctx.logger.warn('[IncomingInvoice] 未找到发票数据');
        return null;
      }
      
      // 获取组织ID（这里简化处理，实际应该从上下文获取）
      const organizationId = 1; // 默认组织ID，实际应从用户上下文获取
      
      // 批量处理发票（使用进项发票服务）
      const incomingInvoiceService = ctx.service.incomingInvoiceService;
      const results = await incomingInvoiceService.batchProcessIncomingInvoices(invoiceList, organizationId);
      
      return {
        success: true,
        data: results,
        invoiceCount: invoiceList.length
      };
    } catch (error) {
      ctx.logger.error('[IncomingInvoice] 从插件数据提取发票信息失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }
  
  /**
   * 判断是否为发票数据
   * @param {Object} pluginData - 插件数据
   */
  isInvoiceData(pluginData) {
    // 根据URL判断是否为发票相关接口
    if (pluginData.url && (pluginData.url.includes('queryFpjcxx') || pluginData.url.includes('qlfpcx') || pluginData.url.includes('queryFpxx') || pluginData.url.includes('fpxxcx'))) {
      return true;
    }
    
    // 根据数据结构判断
    if (pluginData.response && 
        pluginData.response.Response && 
        pluginData.response.Response.Data && 
        pluginData.response.Response.Data.List) {
      const list = pluginData.response.Response.Data.List;
      if (Array.isArray(list) && list.length > 0) {
        // 检查是否存在发票相关字段
        const firstItem = list[0];
        return firstItem.hasOwnProperty('Fphm') && 
               firstItem.hasOwnProperty('Kprq') && 
               firstItem.hasOwnProperty('Hjje');
      }
    }
    
    return false;
  }
  
  /**
   * 解析销项发票列表
   * @param {Object} pluginData - 插件数据
   */
  parseInvoiceList(pluginData) {
    if (!pluginData.response || 
        !pluginData.response.Response || 
        !pluginData.response.Response.Data || 
        !pluginData.response.Response.Data.List) {
      return [];
    }
    
    const rawList = pluginData.response.Response.Data.List;
    const invoiceList = [];
    
    for (const rawInvoice of rawList) {
      const invoice = {
        // 发票基本信息
        invoiceNumber: rawInvoice.Fphm, // 发票号码
        invoiceCode: rawInvoice.ZzfpDm, // 发票代码
        invoiceTypeCode: rawInvoice.FplxDm, // 发票类型代码
        invoiceKindCode: rawInvoice.FppzDm, // 发票种类代码
        invoiceStatusCode: rawInvoice.FpztDm, // 发票状态代码
        isRedInvoice: rawInvoice.Sflzfp, // 是否红字发票
        
        // 销方信息（对于我们来说是购买方）
        sellerTaxNumber: rawInvoice.Xsfnsrsbh, // 销方识别号
        sellerName: rawInvoice.Xsfmc, // 销方名称
        
        // 购方信息（对于我们来说是自己）
        buyerTaxNumber: rawInvoice.Gmfnsrsbh, // 购方识别号
        buyerName: rawInvoice.Gmfmc, // 购方名称
        
        // 金额信息
        invoiceDate: rawInvoice.Kprq, // 开票日期
        totalAmount: rawInvoice.Hjje, // 金额
        taxAmount: rawInvoice.Hjse, // 税额
        totalTaxAmount: rawInvoice.Jshj, // 价税合计
        
        // 其他信息
        invoiceSource: 'tax_system', // 发票来源
        issuer: rawInvoice.Kpr, // 开票人
        taxBureauCode: rawInvoice.XsfssjswjgDm, // 税务机关代码
        taxBureauName: rawInvoice.Xsfssjswjgmc // 税务机关名称
      };
      
      invoiceList.push(invoice);
    }
    
    return invoiceList;
  }
  
  /**
   * 解析进项发票列表
   * @param {Object} pluginData - 插件数据
   */
  parseIncomingInvoiceList(pluginData) {
    if (!pluginData.response || 
        !pluginData.response.Response || 
        !pluginData.response.Response.Data || 
        !pluginData.response.Response.Data.List) {
      return [];
    }
    
    const rawList = pluginData.response.Response.Data.List;
    const invoiceList = [];
    
    for (const rawInvoice of rawList) {
      const invoice = {
        // 发票基本信息
        invoiceNumber: rawInvoice.Fphm, // 发票号码
        invoiceCode: rawInvoice.ZzfpDm, // 发票代码
        invoiceTypeCode: rawInvoice.FplxDm, // 发票类型代码
        invoiceKindCode: rawInvoice.FppzDm, // 发票种类代码
        invoiceStatusCode: rawInvoice.FpztDm, // 发票状态代码
        isRedInvoice: rawInvoice.Sflzfp, // 是否红字发票
        
        // 销方信息（对于我们来说是供应商）
        sellerTaxNumber: rawInvoice.Xsfnsrsbh, // 销方识别号
        sellerName: rawInvoice.Xsfmc, // 销方名称
        
        // 购方信息（对于我们来说是自己）
        buyerTaxNumber: rawInvoice.Gmfnsrsbh, // 购方识别号
        buyerName: rawInvoice.Gmfmc, // 购方名称
        
        // 金额信息
        invoiceDate: rawInvoice.Kprq, // 开票日期
        totalAmount: rawInvoice.Hjje, // 金额
        taxAmount: rawInvoice.Hjse, // 税额
        totalTaxAmount: rawInvoice.Jshj, // 价税合计
        
        // 其他信息
        invoiceSource: 'tax_system', // 发票来源
        issuer: rawInvoice.Kpr, // 开票人
        taxBureauCode: rawInvoice.XsfssjswjgDm, // 税务机关代码
        taxBureauName: rawInvoice.Xsfssjswjgmc // 税务机关名称
      };
      
      invoiceList.push(invoice);
    }
    
    return invoiceList;
  }
}

module.exports = OutgoingInvoiceService;